package cn.anjubao.cp.api.config.security.filter;

import cn.anjubao.cp.api.dto.LoginReqForm;
import cn.anjubao.cp.api.service.UserService;
import cn.anjubao.cp.api.common.ErrorNum;
import cn.anjubao.cp.api.config.security.UserToken;
import cn.anjubao.cp.common.base.BaseResponse;
import cn.anjubao.cp.common.base.exception.BusinessException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.anjubao.parking.municipal.user.dto.UserInfoDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.util.StringUtils;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class LoginFilter extends AbstractAuthenticationProcessingFilter {

    private static final Logger LOG = LoggerFactory.getLogger(LoginFilter.class);

    public static final String LOGIN_URL = "/user/login";

    @Autowired
    private UserService userService;

    public LoginFilter(AuthenticationManager am) {
        super(LOGIN_URL);
        setAuthenticationManager(am);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException{

        if (!"post".equalsIgnoreCase(request.getMethod())) {
            throw new AuthenticationServiceException("此接口只支付POST操作");
        }
        String body = getFromRequest(request);
        LOG.debug("【用户登录】，请求参数：{}", body);
        UserInfoDto userInfoDto=userService.login(checkParams(body));
        UserToken token = new UserToken(userInfoDto);
        return token;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        BaseResponse<UserInfoDto> br = new BaseResponse<>();
        br.setResult(ErrorNum.SUCCESS.code);
        br.setMessage(ErrorNum.SUCCESS.message);
        UserToken token = (UserToken)authResult;
        br.setData(token.getUserInfo());
        response.getWriter().println(JSON.toJSONString(br, SerializerFeature.WriteMapNullValue));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        BaseResponse<String> br = new BaseResponse<>();
        br.setResult(ErrorNum.LOGIN_FAILED.code);
        br.setMessage(failed.getMessage());
        response.getWriter().println(JSON.toJSONString(br));
    }

    private String getFromRequest(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String tmp;
            while ((tmp = br.readLine()) != null) {
                sb.append(tmp);
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    private LoginReqForm  checkParams(String body){
        LoginReqForm reqForm= JSONObject.parseObject(body, LoginReqForm.class);
        if (StringUtils.isEmpty(reqForm.getPhone())){
            throw new AuthenticationServiceException("电话号码不能为空");
        }
        if (StringUtils.isEmpty(reqForm.getVerifyCode())){
            throw new AuthenticationServiceException("手机验证码不能为空");
        }
        return reqForm;
    }
}
